package com.mic.yzzn.plc.common.instructions.request;

import java.util.ArrayList;

import org.apache.commons.lang.StringUtils;

import com.mic.yzzn.plc.common.ins.datastructure.PLCContactorNumber;
import com.mic.yzzn.plc.common.instructions.basic.PLCRequestInstruction;
import com.mic.yzzn.plc.common.toolUtils.PLCContactorCode;

public class PLCMultipleContactorWriteInstruction extends PLCMultipleContactorInstruction
{
	/** 写入数据 */
	protected ArrayList<String> writeData = new ArrayList<String>();
	
	public PLCMultipleContactorWriteInstruction()
	{
		requestCode = PLCRequestInstruction.WRITE_PLURAL_CONTACTOR_INS;
	}

	public ArrayList<String> getWriteData()
	{
		return writeData;
	}

	/**
	 * 触点写入数据set方法
	 * @param writeData
	 */
	public void setWriteData(ArrayList<String> writeData)
	{
		assert(writeData.size() == count);
		this.writeData = writeData;
	}
	
	@Override
	public String initWithString(String instructionString) throws IllegalArgumentException
	{
		String tempResult = super.initWithString(instructionString);
//		System.out.println(tempResult);
		
    	// 判断请求码与当前指令的请求码是否符合
    	int requestCodeLength = requestCode.length();
    	if (!(StringUtils.substring(tempResult, 0, requestCodeLength).equals(requestCode)))
		{
			throw new IllegalArgumentException("PLCSingleContactorReadInstruction's requestCode must be \"" + requestCode +"\"");
		}
    	
    	// 截取请求码
    	tempResult = StringUtils.substringAfter(tempResult, requestCode);
//		System.out.println(tempResult);

    	// 读取触点数量
		int c = Integer.parseInt(tempResult.substring(0, 1));
    	setCount(c);
    	// 截取触点数量
    	tempResult = tempResult.substring(1);
    	
//		System.out.println(tempResult);

		// 检测读取触点数量是否错误
		if (c != tempResult.length() / 6)
		{
			throw new IllegalArgumentException("PLCSingleContactorReadInstruction's count must equal to the number of contactorCode and contactorNumber");
		}
		
    	// 取得触点代码和触点编号
    	int codeBegin = 0;
    	for (int i = 0; i < count; ++i)
    	{
    		codeBegin = i * 6;
    		// 设置触点代码
    		String contactorCode = tempResult.substring(codeBegin, codeBegin + 1);
    		String cNumber = tempResult.substring(codeBegin + 1, codeBegin + 1 + 4);
    		// 设置触点编号
    		PLCContactorNumber contactorNumber = new PLCContactorNumber(cNumber.substring(0, 3), cNumber.charAt(3));
    		// 设置触点数据
    		String data = tempResult.substring(codeBegin + 1 + 4, codeBegin + 1 + 4 + 1);
    		if (!data.equals(PLCContactorCode.PLC_CONTACTOR_OFF) && !data.equals(PLCContactorCode.PLC_CONTACTOR_ON))
			{
    			throw new IllegalArgumentException("contactor data must be \"1\" or \"0\"");
			}
    		
    		contactorCodes.add(contactorCode);
    		contactorNumbers.add(contactorNumber);
    		writeData.add(data);
    	}
		
    	tempResult = tempResult.substring(5 * count);
    	
		return tempResult;
	}
	
	/**
	 * 计算并返回每一位的异或
	 */
	@Override
	protected int getXORByBit()
	{
        int i = 0;
        int result = 0;
        for (i = 0; i < contactorCodes.size(); ++i)
        {
        	String data = writeData.get(i);
        	for (int j = 0; j < data.length(); ++j)
        	{
        		result ^= data.charAt(j);
        	}
        }
        
        return super.getXORByBit() ^ result;
	}
	
    /**
     * 转化成字符串
     */
    @Override
    public String toString()
    {
        // 拼接指令字符串
        StringBuffer buffer = new StringBuffer();
        buffer.append(instructionHeader);
        buffer.append(locationNumber_high);
        buffer.append(locationNumber_low);
        buffer.append(instructionTypeCode);
        buffer.append(requestCode);
        buffer.append(count);
        for (int i = 0; i < count; ++i)
        {
        	buffer.append(contactorCodes.get(i) + contactorNumbers.get(i));
        	buffer.append(writeData.get(i));
        }
        buffer.append(getBBC_high());
        buffer.append(getBBC_low());
        buffer.append(instructionEnd);

        return buffer.toString();
    }
}
